﻿#include "pch.h"
#include "staticRouter.h"
#include "oatpp/web/protocol/http/incoming/SimpleBodyDecoder.hpp"

#include "oatpp/web/protocol/http/incoming/BodyDecoder.hpp"
#include "oatpp/network/Url.hpp"
#include "oatpp/web/protocol/http/incoming/Request.hpp"

//保持接口统一下的妥协方案,包装类声明需要与原始类保持一致
class PackingWoHTTPContext {
public:
	bool m_Next;
	int m_index;
	int m_max;
	std::vector<WoHttpControllerModel>* m_CallFunc;
	std::map<std::string, std::string> m_formMap;
	inja::json m_bodyMap;
};
class PackingInputStreamBufferedProxy : public oatpp::base::Countable, public oatpp::data::stream::BufferedInputStream {
public:
	std::shared_ptr<oatpp::data::stream::InputStream> m_inputStream;
	oatpp::data::share::MemoryLabel m_memoryLabel;
	oatpp::data::buffer::FIFOBuffer m_buffer;
};
class PackingFIFOBuffer {
public:
	p_char8 m_buffer;
	v_buff_size m_bufferSize;
	v_buff_size m_readPosition;
	v_buff_size m_writePosition;
	bool m_canRead;
};


#define _WOAPP_ROUTER_CONTEXT_ "_WOAPP_ROUTER_CONTEXT_"	//路由上下文

void _ParseMediaType(std::string& ct, std::string& mediatype) {
	std::vector<std::string> s;
	WoHaperStringSplitWithStlA(ct, ";", s);
	for (int i = 0; i < s.size(); i++) {
		WoHaperStringTrimA(s[i], s[i]);
		if (s[i].find("/")!=std::string::npos) {
			mediatype = s[i];
			return;
		}
	}

}

void _AnalysisBody(const WoHTTPIncomingRequestPtr& req, CXBytes&r) {
	//r.clear();
	//auto handers = req->getHeaders();
	//auto ContentLength = atoi(handers.get("Content-Length").getPtr()->c_str());
	//if (ContentLength<1) {
	//	r.setTextA("");
	//	return ;
	//}
	//auto bs = req->getBodyStream();
	//auto bp = (PackingInputStreamBufferedProxy*)bs.get();
	//auto buffptr = (PackingFIFOBuffer*) & bp->m_buffer;
	//if (buffptr->m_bufferSize < ContentLength || buffptr->m_buffer==nullptr) {
	//	r.setTextA("");
	//	return;
	//}
	//int size = (buffptr->m_writePosition > max) ? max : (buffptr->m_writePosition- buffptr->m_readPosition);
	//if (buffptr->m_writePosition - buffptr->m_readPosition < size) {
	//	r.setTextA("");
	//	return;
	//}
	//char* lbody = new char[size +1];
	//memset(lbody,0, size +1);
	//memcpy(lbody, buffptr->m_buffer+(buffptr->m_readPosition), size);
	//r.add(lbody, size + 1);
	//delete[] lbody;
	WoRequestGetBodyToByte(req, r);
	return;
}

WoRequestHandler::WoRequestHandler(WoHttpControllerModel& CallFunc) {
	if (CallFunc.model==0) {
		if (CallFunc.func!=nullptr) {
			m_CallFunc.push_back(CallFunc);
		}
	}
}
WoRequestHandler::WoRequestHandler(CXVector<WoHttpControllerModel>& CallFuncs) {
	m_CallFunc.assign(CallFuncs.getVector()->begin(), CallFuncs.getVector()->end());
}

const WoHttpControllerModel& WoRequestHandler::GetEndHandler() {
	return m_CallFunc.size() == 0 ? WoHttpControllerModel() : m_CallFunc[m_CallFunc.size()-1];
}
const std::vector<WoHttpControllerModel>& WoRequestHandler::GetHandlers() {
	return m_CallFunc;
}

void RequesSwitchControllerMethod(
	const std::shared_ptr<oatpp::web::server::HttpRequestHandler::IncomingRequest>& request,
	const WoHttpControllerModel&cm,
	WoHTTPContext&context,
	std::string& method) {
	//auto& method =  request->getStartingLine().method;
	if(method=="CONNECT") {
		cm.routerHandle->CONNECT(context);
	}
	else if(method=="DELETE") {
		cm.routerHandle->DELETE_(context);
	}
	else if (method == "GET") {
		cm.routerHandle->GET(context);
	}
	else if (method == "HEAD") {
		cm.routerHandle->HEAD(context);
	}
	else if(method=="OPTIONS") {
		cm.routerHandle->OPTIONS(context);
	}
	else if(method=="PATCH") {
		cm.routerHandle->PATCH(context);
	}
	else if(method=="POST") {
		cm.routerHandle->POST(context);
	}
	else if(method=="PUT") {
		cm.routerHandle->PUT(context);
	}
	else if(method=="TRACE") {
		cm.routerHandle->TRACE(context);
	}
}

std::shared_ptr<oatpp::web::protocol::http::outgoing::Response>
WoRequestStaticHandler::handle(const std::shared_ptr<IncomingRequest>& request) {
	//获取请求原地址
	std::string tailPath = request->getPathTail();
	tailPath = tailPath.substr(m_urlPath.length() - 1, tailPath.length());
	//将请求地址转换为文件列表地址
	std::string filePath = "/" + tailPath;

	std::cout << filePath << std::endl;
	auto& f = m_fileList[filePath];
	if (!f.isSet) {
		throw HttpError(Status::CODE_404, "404 page not found");;
	}
	//_Wo_Files_GetFileMIMEType
	std::string fsPath = m_filePath + tailPath;
	auto resp = ResponseFactory::createResponse(Status::CODE_200, oatpp::String::loadFromFile(fsPath.c_str()));
	resp->putHeader("Content-Type", _Wo_Files_GetFileMIMEType(fsPath.c_str()).get());
	// 终止时间
	auto end_time = std::chrono::high_resolution_clock::now();
	auto elapsed_time = std::chrono::duration_cast<std::chrono::nanoseconds>(end_time - request->m_start_time).count();
	g_logger->info("| [{:^5}] | [{:^9}] | {:>10} | {}", resp->getStatus().code,
		std::string((char*)request->getStartingLine().method.getData(), request->getStartingLine().method.getSize()),
		WoHaperTimeconversion(elapsed_time),
		std::string((char*)request->getStartingLine().path.getData(), request->getStartingLine().path.getSize()));
	return resp;
};

std::shared_ptr<oatpp::web::protocol::http::outgoing::Response> 
WoRequestHandler::handle(const std::shared_ptr<IncomingRequest>& request) {
	if (m_CallFunc.size()==0) {
		return ResponseFactory::createResponse(Status::CODE_200, "");
	}
	//WoHTTPContext ctx(request, resp);
	try {
		WoHTTPOutgoingResponsePtr resp = ResponseFactory::createResponse(Status::CODE_200, "");
		resp->putHeader("Content-Type","text/html; charset=utf-8");
		auto ctx = std::make_shared<WoHTTPContext>(request, resp);
		int num = (int)m_CallFunc.size();
		auto ct = request->getHeader("Content-Type");
		if ((ct.get() == nullptr?"": ct->c_str()) == "") {
			//ct = _AnalysisMimeType(request);
			ct = WEB_OCTET_STREAM;
			request->putHeader("Content-Type", WEB_OCTET_STREAM);
		}
		auto pc = (PackingWoHTTPContext*)ctx.get();
		pc->m_index = 0;
		pc->m_CallFunc = &m_CallFunc;
		pc->m_max = num;
		pc->m_Next = true;
		std::string medtype;

		_ParseMediaType(*ct.getPtr(), medtype);
		CXBytes lbody;
		
		auto& l_methodData =request->getStartingLine().method;
		std::string l_method((char*)l_methodData.getData(), l_methodData.getSize());


		if (request->getHeaders().getAsMemoryLabel<oatpp::data::share::StringKeyLabelCI>(Header::TRANSFER_ENCODING)) {
			WoRequestGetBodyToByte(request, lbody);
		}
		else if (request->getHeaders().getAsMemoryLabel<oatpp::data::share::StringKeyLabel>(Header::CONTENT_LENGTH)) {
			WoRequestGetBodyToByte(request, lbody);
		}
		else {
			auto connectionStr = request->getHeaders().getAsMemoryLabel<oatpp::data::share::StringKeyLabelCI>(Header::CONNECTION);
			if (connectionStr && connectionStr == "close") {
				WoRequestGetBodyToByte(request, lbody);
			}
		}
		if (medtype == "application/x-www-form-urlencoded") {
			CXBytes lp("http://localhost/parse?");
			lp.add((void*)lbody.get(), lbody.size());
			WoHTTPParseUrl u;
			u.ParseUrl(lp.getTextPtrA(), u.v_param);
			for (auto iter: u.v_param.uri_map) {
				//pc->m_bodyMap[WoCodingUTF82GBK(WoCodingUrlDecodeA(iter.first.c_str())).get()]
				//	= WoCodingUTF82GBK(WoCodingUrlDecodeA(iter.second.c_str()));
				
				pc->m_bodyMap[WoCodingUrlDecodeA(iter.first.c_str()).get()]
					= WoCodingUrlDecodeA(iter.second.c_str());
			}
		}else if(medtype == "application/json"){
			pc->m_bodyMap = inja::json::parse(lbody.getTextPtrA());
		}
		request->putBundleData(_WOAPP_ROUTER_CONTEXT_,
			oatpp::Int64((INT64)ctx.get())
		);
		while (pc->m_index < num) {
			if (!pc->m_Next) {
				break;
			}
			auto model = m_CallFunc[ctx->Index()];
			if (model.model==0) {
				((WoHTTPHanderFunc)m_CallFunc[ctx->Index()].func)(*ctx.get());
			}
			else if (model.model==1) {
				//auto startingLine = request->getStartingLine();
				//auto method = (const char*)startingLine.method.getData();
				//auto iLen = startingLine.method.getSize();
				RequesSwitchControllerMethod(request, m_CallFunc[ctx->Index()], *ctx.get(),l_method);
			}
			
			ctx->Index(ctx->Index() + 1);
		}
		
		// 终止时间
		auto end_time = std::chrono::high_resolution_clock::now();
		auto elapsed_time = std::chrono::duration_cast<std::chrono::nanoseconds>(end_time - request->m_start_time).count();
		//MessageBoxA(0, std::to_string(resp->getBody()->getKnownSize()).c_str(),0,0);
		//auto properties = request->getConnection()->getInputStreamContext().getProperties();
		//context.getProperties();

		// Get the client's IP address from the connection object

		g_logger->info("| [{:^5}] | [{:^9}] | {:>10} | {}", resp->getStatus().code, 
			std::string((char*)request->getStartingLine().method.getData(), request->getStartingLine().method.getSize()), 
			WoHaperTimeconversion(elapsed_time),
			std::string((char*)request->getStartingLine().path.getData(), request->getStartingLine().path.getSize()));
		return resp;
	}catch (oatpp::web::protocol::http::HttpError& httpError) {
		//auto rec = (HttpRequestHandlerErrorFunc)request->GetHttpRequestHandlerErrorCallback();
		/*if (rec) {
			return rec(request,std::make_shared<oatpp::web::protocol::http::HttpError>(httpError));
		}*/
		//if (g_handerError != nullptr) {
		//	auto resp = oatpp::web::protocol::http::outgoing::ResponseFactory::createResponse(
		//		httpError.getInfo().status, httpError.getMessage()
		//	);
		//	WoHTTPContext ctx(request, resp);
		//	g_handerError(ctx);
		//}
		return GlobalHandlerError(request, std::make_shared<oatpp::web::protocol::http::HttpError>(httpError));
	}
	catch (std::exception& err) {
		////auto rec = (HttpRequestHandlerErrorFunc)GetHttpRequestHandlerErrorCallback();
		//if (rec) {
		//	return rec(request, std::make_shared<oatpp::web::protocol::http::HttpError>(Status::CODE_503, err.what()));
		//}
		//if (g_handerError != nullptr) {
		//	auto resp = oatpp::web::protocol::http::outgoing::ResponseFactory::createResponse(
		//		oatpp::web::protocol::http::Status(503, err.what()), err.what()
		//	);
		//	WoHTTPContext ctx(request, resp);
		//	g_handerError(ctx);
		//}
		return GlobalHandlerError(request, std::make_shared<oatpp::web::protocol::http::HttpError>(Status::CODE_503, err.what()));
	}
	catch (...) {
		std::rethrow_exception(std::current_exception());
		//auto rec = (HttpRequestHandlerErrorFunc)GetHttpRequestHandlerErrorCallback();
		//if (rec) {
		//	return rec(request, 
		//		std::make_shared<oatpp::web::protocol::http::HttpError>(Status::CODE_503, "An unknown error has occurred"));
		//}
	}
	return ResponseFactory::createResponse(Status::CODE_503, "Service Unavailable");
}

void WEBOAT_API WoHTTPThrowException(int code,const char*msg) {
	//throw oatpp::web::protocol::http::HttpError(oatpp::web::protocol::http::Status(code,""), msg);
	throw oatpp::web::protocol::http::HttpError(oatpp::web::protocol::http::Status(code,msg), msg);
}

WoRequestHandlerPtr WEBOAT_API WoCreateRequestHandler(WoHttpControllerModel& CallFunc) {
	return std::make_shared<WoRequestHandler>(CallFunc);
}
WoRequestHandlerPtr WEBOAT_API WoCreateRequestHandlerEx(CXVector<WoHttpControllerModel>&funcs) {
	return std::make_shared<WoRequestHandler>(funcs);
}

void WEBOAT_API WoRequestHanderNext(const WoHTTPIncomingRequestPtr& req) {
	auto ptr = req->getBundleData<oatpp::Int64>(_WOAPP_ROUTER_CONTEXT_);
	auto context = *(WoHTTPContext**)ptr.getPtr().get();
	context->Next(true);
	context->Index(context->Index()+1);
	while (context->Index() < context->Max()) {
		if (!context->GetNext()) {
			break;
		}
		auto model = context->CallModel(context->Index());
		if (model.model==0) {
			if (model.func != nullptr) {
				model.func(*context);
			}
		}
		else if (model.model == 1) {
			auto& l_methodData = req->getStartingLine().method;
			std::string l_method((char*)l_methodData.getData(), l_methodData.getSize());
			RequesSwitchControllerMethod(req, model, *context, l_method);
		}
		context->Index(context->Index()+1);
	}
}

void WEBOAT_API WoRequestHanderAbort(const WoHTTPIncomingRequestPtr& req) {
	auto ptr = req->getBundleData<oatpp::Int64>(_WOAPP_ROUTER_CONTEXT_);
	auto context = *(WoHTTPContext**)ptr.getPtr().get();
	context->Next(false);
}

CXTextA WEBOAT_API WoRequestGetPathVariable(const WoHTTPIncomingRequestPtr& req,const char*key) {
	auto rptr = req->getPathVariable(key);
	return rptr? rptr->c_str():"";
}

void WEBOAT_API WoRequestGetPathVariables(const WoHTTPIncomingRequestPtr& req, CXMap<CXTextA, CXTextA>& rmap) {
	auto map = req->getPathVariables();
	auto vs = map.getVariables();
	rmap.clear();
	for (auto i = vs.begin(); i != vs.end(); i++) {
		rmap[i->first.toString().getPtr()->c_str()]= i->second.toString().getPtr()->c_str();
	}
}

CXTextA WEBOAT_API WoRequestGetQueryParameter(const WoHTTPIncomingRequestPtr& req, const char* key) {
	auto rptr = req->getQueryParameter(WoCodingUrlEncodeA(key).get()).getPtr();
	return rptr? rptr->c_str():"";
}

CXTextA WEBOAT_API WoRequestGetPathTail(const WoHTTPIncomingRequestPtr& req) {
	return req->getPathTail()->c_str();
}

CXTextA WEBOAT_API WoRequestGetHeader(const WoHTTPIncomingRequestPtr& req,const char* key) {
	auto rptr = req->getHeader(key);
	return rptr ? rptr->c_str() : "";
}

void WEBOAT_API WoRequestGetHeaders(const WoHTTPIncomingRequestPtr& req, CXMap<CXTextA, CXTextA>& rmap) {
	auto headers = req->getHeaders();
	auto ahds = headers.getAll();
	rmap.clear();
	for (auto i = ahds.begin(); i != ahds.end(); i++) {
		rmap[i->first.toString().getPtr()->c_str()] = i->second.toString().getPtr()->c_str();
	}
}

void WEBOAT_API WoRequestGetBodyToString(const WoHTTPIncomingRequestPtr& req,CXTextA& str) {
	auto bodyStreamPtr = req->getBodyStream();
	auto bodyInputStreamPtr = (PackingInputStreamBufferedProxy*)bodyStreamPtr.get();
	auto buffptr = (PackingFIFOBuffer*)&bodyInputStreamPtr->m_buffer;
	auto buffSize = buffptr->m_writePosition;
	auto pointIndex = 0;
	if (buffSize <= 4) {
		str="";
		return;
	}
	for (size_t i = 0; i < (buffSize - 4); i++) {
		if (buffptr->m_buffer[i] == '\r' &&
			buffptr->m_buffer[i + 1] == '\n' &&
			buffptr->m_buffer[i + 2] == '\r' &&
			buffptr->m_buffer[i + 3] == '\n') {
			pointIndex = i + 4;
			break;
		}
	}
	if (pointIndex >= buffSize || pointIndex == 0) {
		str="";
		return;
	}
	str.append2((const char*)&(buffptr->m_buffer[pointIndex]), buffSize - pointIndex);
}

void WEBOAT_API WoRequestGetBodyToByte(const WoHTTPIncomingRequestPtr& req, CXBytes& data) {
	auto bodyStreamPtr = req->getBodyStream();
	auto bodyInputStreamPtr = (PackingInputStreamBufferedProxy*)bodyStreamPtr.get();
	auto buffptr = (PackingFIFOBuffer*) &bodyInputStreamPtr->m_buffer;
	auto buffSize = buffptr->m_writePosition;
	auto pointIndex = 0;
	if (buffSize<=4) {
		data.clear();
		return;
	}
	for (size_t i = 0; i < (buffSize-4); i++) {
		if(buffptr->m_buffer[i]=='\r' &&
			buffptr->m_buffer[i+1] == '\n'&& 
			buffptr->m_buffer[i+2] == '\r' &&
			buffptr->m_buffer[i + 3] == '\n') {
			pointIndex = i+4;
			break;
		}
	}
	if(pointIndex >= buffSize || pointIndex==0){
		data.clear();
		return;
	}
	data.add((void*)&(buffptr->m_buffer[pointIndex]), buffSize-pointIndex);
}

CXTextA WEBOAT_API WoRequestGetPostForm(WoHTTPContext* ctx,const char*key) {
	if (ctx==nullptr)
	{
		return "";
	}
	auto c = (PackingWoHTTPContext*)ctx;
	return c->m_bodyMap.count(key)==0?"": c->m_bodyMap.at(key).get<std::string>();
}

CXTextA WEBOAT_API WoRequestGetPath(const WoHTTPIncomingRequestPtr& req) {
	return req->getStartingLine().path.toString().getPtr()->c_str();
}

//void _RequestPraseJsonToBind(WoHTTPContext* ctx, CXTextA &str, WoRefInfo* refInfo, void* refPtr) {
//	inja::json json=inja::json::parse(str.get());
//	for (auto iter = json.begin(); iter != json.end(); ++iter) {
//		auto vType = iter.value().type();
//		switch (vType)
//		{
//		case nlohmann::detail::value_t::null:
//			break;
//		case nlohmann::detail::value_t::object:
//			break;
//		case nlohmann::detail::value_t::array:
//			break;
//		case nlohmann::detail::value_t::binary:
//			break;
//		case nlohmann::detail::value_t::discarded:
//			break;
//		default:
//			//值类型
//			auto key = WoCodingUTF82GBK(iter.key().c_str());
//			auto mamber = refInfo->member[key.get()];
//			if (mamber == nullptr) { break; }
//			auto funcrow = typeNameList[mamber->typeName];
//			if (funcrow != nullptr) {
//				if (!funcrow(refPtr, mamber, WoCodingGBK2UTF8(iter.value().get<std::string>().c_str()))) {
//					throw "反射出错";
//					return;
//				}
//			}
//			break;
//		}
//	}
//}

//bool WEBOAT_API WoRequestGetPostToBind(WoHTTPContext* ctx, WoRefIterator& iter, void* ptr) {
//	if (ptr == nullptr) {
//		throw "WoRequestGetPostToBind: 填充ptr为NULL";
//		return false;
//	}
//	if (iter==g_RefMap.end()){
//		throw "WoRequestGetPostToBind: 模型句柄错误！";
//		return false;
//	}
//	auto refInfo = iter->second;
//	if (refInfo == nullptr) {
//		throw "WoRequestGetPostToBind: 反射未注册";
//		return false;
//	};
//	auto ct = WoRequestGetHeader(*ctx, "Content-Type");
//	if (ct == "application/x-www-form-urlencoded") {
//		for (auto iters = ((PackingWoHTTPContext*)ctx)->m_bodyMap.begin(); 
//			iters != ((PackingWoHTTPContext*)ctx)->m_bodyMap.end(); iters++) {
//			auto k = iters.key().c_str();
//			auto mamber = refInfo->member[iters.key().c_str()];
//			if (mamber == nullptr) { continue; }
//			auto funcrow = typeNameList[mamber->typeName];
//			if (funcrow != nullptr) {
//				
//				if (!funcrow(ptr, mamber, iters.value().get<std::string>().c_str())) {
//					return false;
//				}
//			}
//		}
//	}
//	else if (ct == "application/json") {
//		CXTextA str;
//		WoRequestGetBodyToString(*ctx,str);
//		try
//		{
//			_RequestPraseJsonToBind(ctx, str, refInfo,ptr);
//		}
//		catch (const inja::json::exception& jserr) {
//			throw jserr.what();
//			return false;
//		}
//		catch (...) {
//			throw "WoRequestGetPostToBind: 解析json时出现未知异常！";
//			return false;
//		}
//		return true;
//	}
//	return false;
//}

void _WoFillJsonData_get_to(inja::json* jsonMap, nlohmann::detail::value_t value,void* func,void *ptr,int deviation) {
	if (func == nullptr) {
		//防止空指针
		return;
	}
	switch (value)
	{
	case nlohmann::json_abi_v3_11_2::detail::value_t::null:
		break;
	case nlohmann::json_abi_v3_11_2::detail::value_t::string:
		((WoRefBaseModelFunc)func)((void*)((WOPTR)ptr + deviation), (*jsonMap).get<std::string>().c_str());
		break;
	case nlohmann::json_abi_v3_11_2::detail::value_t::boolean:
		((WoRefBaseModelFunc)func)((void*)((WOPTR)ptr + deviation), std::to_string((*jsonMap).get<bool>()).c_str());
		break;
	case nlohmann::json_abi_v3_11_2::detail::value_t::number_integer:
		((WoRefBaseModelFunc)func)((void*)((WOPTR)ptr + deviation), std::to_string((*jsonMap).get<long long>()).c_str());
		break;
	case nlohmann::json_abi_v3_11_2::detail::value_t::number_unsigned:
		((WoRefBaseModelFunc)func)((void*)((WOPTR)ptr + deviation), std::to_string((*jsonMap).get<unsigned long long>()).c_str());
		break;
	case nlohmann::json_abi_v3_11_2::detail::value_t::number_float:
		((WoRefBaseModelFunc)func)((void*)((WOPTR)ptr + deviation), std::to_string((*jsonMap).get<float>()).c_str());
		break;
	default:
		break;
	}
}

void WoRefFillJsonData(WoTemplateJson* jsonMap,    //传入并且解析后的JSON
	const char* keyName,   //被映射的变量名
	const char* typeName,	//变量的原型类型
	void* ptr,   //欲写入的地址
	int deviation //欲写入地址的偏移
) {
	//判断传入键值表是否有映射的键
	auto value = (*jsonMap)[keyName];
	//没有就下一个
	if (value == nullptr) { return; }
	WoRefModelHandle refInfo = nullptr;
	refInfo = WoRefTypeNameGetHandle(typeName);
	//防止空指针
	if (refInfo == nullptr) { return; }
	//if (value.type() != nlohmann::detail::value_t::array) {
	//	//有且不为数组就进入反射事件
	//	refInfo = WoRefTypeNameGetHandle(typeName.data());
	//	//防止空指针
	//	if (refInfo == nullptr) { return; }
	//}
	WoRefModelHandle objPtr = nullptr;
	switch (value.type()) {
	case nlohmann::detail::value_t::null:
		break;
	case nlohmann::detail::value_t::object:
		objPtr = WoRefTypeNameGetHandle(refInfo->typeName.c_str());
		//防止空
		if (objPtr == nullptr) { 
			//class std::vector<int, class std::allocator<int> >
			//class CXVector<int>
			break;
		}
		//遍历子成员 <映射值,对应键>
		for (auto iters = objPtr->memberMap.begin(); iters != objPtr->memberMap.end(); iters++) {
			WoRefFillJsonData(&value,		//传递子json对象
				iters->first.c_str(),	//将key转码
				iters->second->typeName.c_str(), //类型名称传递
				(void*)((WOPTR)ptr), //移动写入地址
				deviation+iters->second->deviation);
		}
		break;
	case nlohmann::detail::value_t::array: {
		std::string arrName;
		WoRefArrarType arrType;
		if (!WoRefIfisList(typeName, &arrName, &arrType)) {
			break;
		}
		//数组事件
		objPtr = WoRefTypeNameGetHandle(arrName.c_str());
		//防止空
		if (objPtr == nullptr) {
			break;
		}
		auto s = value.dump();
		refInfo->refFunc((void*)(((WOPTR)ptr) + deviation), s.c_str());
		//
		//class CXVector<struct Capt>
		//std::string arrName;
		//WoRefArrarType arrType;
		//if (!WoRefIfisList(typeName, &arrName, &arrType)) {
		//	break;
		//}
		////非数组嵌套(数组内为key->value)
		//if (!WoRefIfisList(arrName)) {
		//	//正常处理常规数组
		//	refInfo = WoRefTypeNameGetHandle(arrName.data());
		//	if (refInfo==nullptr) {
		//		break;
		//	}
		//	if (arrType == WoRefArrarType::cxvector) {
		//		if (memberInfo->arrayFunc.SizeFunc==nullptr) {
		//			break;
		//		}
		//		//因为c++无法动态确定stl的类型,所以只能曲线救国
		//		//类化一个1字节宽的容器
		//		CXVector<char>* ArrPtr = (CXVector<char>*)ptr;
		//		//开扩内存,内存尺寸为记录的大小
		//		//(啊哈哈哈哈哈哈~~~我是天才awa~~~)
		// 
		// 
		//		//妈的dll内内存与exe代码隔离,我是傻逼,焯
		//		//typedef int (CXVector<char>::* sizeFuncPtr)();
		//		//sizeFuncPtr* sptr = (sizeFuncPtr*)(memberInfo->arrayFunc.SizeFunc);
		//		//auto VecPtr=(ArrPtr->*(*sptr))();
		//		auto VecPtr = ArrPtr->size();
		//		std::cout << "1";
		//		//auto ArrVecPtr = static_cast<getVectorFuncPtr*>(refInfo->refFunc);
		//		

		//	}
			
			//_WoFillJsonData();
		//}
		break;
	}
	case nlohmann::detail::value_t::binary:
		break;
	case nlohmann::detail::value_t::discarded:
		break;
	default:
		_WoFillJsonData_get_to(&value, value.type(), refInfo->refFunc,ptr,deviation);
		break;
	}
}

bool WEBOAT_API WoRefFillPtrToJson(WoTemplateJson *json,const char* typeName, void* ptr) {
	if (ptr == nullptr) {
		throw std::exception("WoRefFillPtrToJson: 填充ptr为NULL");
		return false;
	}
	auto info = WoRefTypeNameGetHandle(typeName);
	if (info == nullptr) {
		throw std::exception("WoRefFillPtrToJson: 模型未注册！");
		return false;
	}
	if (ptr == nullptr) {
		throw std::exception("WoRefFillPtrToJson: 填充ptr为NULL");
		return false;
	}
	if (!info->isNesting) {
		throw std::exception("WoRefFillPtrToJson: 错误的反射模型");
		return false;
	}
	if (json == nullptr) {
		throw std::exception("WoRefFillPtrToJson: json错误");
		return false;
	}
	//遍历需要反射的结构体成员
	for (auto iters = info->memberMap.begin(); iters != info->memberMap.end(); iters++) {
		WoRefFillJsonData(json, iters->first.c_str(), iters->second->typeName.c_str(), ptr, iters->second->deviation);
	}
	return true;
}

bool WEBOAT_API WoRequestGetPostToBind(WoHTTPContext* ctx, const char* typeName, void* ptr) {
	if (ptr == nullptr) {
		throw std::exception("WoRequestGetPostToBind: 填充ptr为NULL");
		return false;
	}
	auto info = WoRefTypeNameGetHandle(typeName);
	if (info == nullptr) {
		throw std::exception("WoRequestGetPostToBind: 模型未注册！");
		return false;
	}
	if (ptr == nullptr) {
		throw std::exception("WoRequestGetPostToBind: 填充ptr为NULL");
		return false;
	}
	if (!info->isNesting) {
		throw std::exception("WoRequestGetPostToBind: 错误的反射模型");
		return false;
	}
	auto ct = WoRequestGetHeader(*ctx, "Content-Type");
	if (ct == "application/x-www-form-urlencoded") {
		auto& jsonMap = ((PackingWoHTTPContext*)ctx)->m_bodyMap;
		//遍历需要反射的结构体成员
		for (auto iters = info->memberMap.begin(); iters != info->memberMap.end(); iters++) {
			//判断键值表是否有键
			auto t = jsonMap[iters->first];
			if (t==nullptr) {
				//没有就下一个
				continue;
			}
			//有就进入反射事件
			auto refInfo = WoRefTypeNameGetHandle(iters->second->typeName.c_str());
			if (refInfo==nullptr) {
				//防止空指针
				continue;
			}
			if (refInfo->isNesting) {
				//urlencoded不处理嵌套
				continue;
			}
			if (refInfo->refFunc==nullptr) {
				//防止空指针
				continue;
			}
			((WoRefBaseModelFunc)refInfo->refFunc)((void*)((WOPTR)ptr+ iters->second->deviation), t.get<std::string>().c_str());
		}
	}
	else if (ct == "application/json") {
		auto& jsonMap = ((PackingWoHTTPContext*)ctx)->m_bodyMap;
		//遍历需要反射的结构体成员
		for (auto iters = info->memberMap.begin(); iters != info->memberMap.end(); iters++) {
			WoRefFillJsonData(&jsonMap,iters->first.c_str(), iters->second->typeName.c_str(),ptr, iters->second->deviation);
		}
	}

	return false;
}

#include "WoJWT.h"

CXTextA WoRequestGetJWTAuthStr(const WoHTTPIncomingRequestPtr& req,const char*hander,const char* prefix) {
	std::string lPrefix = prefix == "" ? "Bearer " : std::string(prefix)+" ";
	std::string lHander = hander == "" ? "Authorization" : hander;
	std::string h = req->getHeader(lHander.c_str());
	auto ber = h.substr(0, lPrefix.length());
	if (ber != lPrefix) {
		return "";
	}
	return h.substr(lPrefix.length(), h.length() - lPrefix.length());
}